package com.dreamchaser.familydevice.config.device;


import com.dreamchaser.familydevice.config.SpringContextHolder;
import com.dreamchaser.familydevice.service.IDeviceService;
import com.dreamchaser.familydevice.util.device.ByteBufUtil;
import com.dreamchaser.familydevice.util.device.ByteHexUtil;
import com.dreamchaser.familydevice.util.device.DeviceDataUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;

/***
 *
 *
 * @Author: SJie
 * Date: 2019/12/19 下午5:44
 * Description:
 *
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {
    int readIdleTimes = 0;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("=== " + ctx.channel().remoteAddress() + " is active ===");
        DeviceDataUtil.add(ctx.channel());
        // 请求设备号
        int[] data = {0x00};
        ByteBuf byteBuf = ByteBufUtil.hexToByteBuf(data);
        log.info("请求设备号");
        ctx.channel().writeAndFlush(byteBuf);

        // 发送一次心跳，目的是请求设备上的组件状态

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        int device = DeviceDataUtil.getDeviceCode(ctx.channel());
        DeviceDataUtil.remove(ctx.channel());
        log.info(device+"号："+"关闭连接");
        super.channelInactive(ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        readIdleTimes = 0;
        byte[] data = ByteBufUtil.ByteBufToBytes(msg);
        int device = DeviceDataUtil.getDeviceCode(ctx.channel());
        if (ByteHexUtil.byteToHex(data[0]) == 0xff) {
            log.info(device + "号:设备心跳");
            log.info(device + "号:状态"+ByteHexUtil.bytesToHexStr(data).substring(3));

            IDeviceService deviceService = SpringContextHolder.getBean(IDeviceService.class);
            deviceService.setDeviceStatus(DeviceDataUtil.getDeviceExpressionBydeviceCode(device), data);
        } else {
            ctx.fireChannelRead(data);

        }
        ReferenceCountUtil.release(msg);


    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        IdleStateEvent event = (IdleStateEvent) evt;

        String eventType = null;
        switch (event.state()) {
            case READER_IDLE:
                eventType = "server:读空闲";

                break;
            case WRITER_IDLE:
                eventType = "server:写空闲";

                break;
            case ALL_IDLE:
                eventType = "server:读写空闲";
                readIdleTimes++; // 读写空闲的计数加1
                int[] data = {0xff};
                ByteBuf byteBuf = ByteBufUtil.hexToByteBuf(data);
                ctx.writeAndFlush(byteBuf);
// 不处理
                break;
        }
        //System.out.println(ctx.channel().remoteAddress() + "超时事件：" + eventType);
        if (readIdleTimes > 2) {
            DeviceDataUtil.remove(ctx.channel());
            System.out.println(" [server]读空闲超过4次，关闭连接");
//            ctx.channel().writeAndFlush("you are out");
            ctx.channel().close();
        }
        //System.out.println("readIdleTimes:"+readIdleTimes);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();

        super.exceptionCaught(ctx, cause);
    }
}
